package com.tbit.uqbike.webmanager.controller;

import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.tbit.uqbike.constant.SysConstant;
import com.tbit.uqbike.constant.UserConstant;
import com.tbit.uqbike.enums.SystemCodeEnum;
import com.tbit.uqbike.manager.exception.BaseException;
import com.tbit.uqbike.object.business.PageData;
import com.tbit.uqbike.object.pojo.MachineOperationsStat;
import com.tbit.uqbike.object.pojo.MachineStatusFlag;
import com.tbit.uqbike.object.pojo.dto.MachineOperationsStatDownloadDTO;
import com.tbit.uqbike.object.pojo.vo.MachineOperationsStatChartVO;
import com.tbit.uqbike.object.value.LoginInfo;
import com.tbit.uqbike.object.view.JsonResult;
import com.tbit.uqbike.object.view.MachineInfo;
import com.tbit.common.entity.view.PageResult;
import com.tbit.common.entity.view.Result;
import com.tbit.uqbike.service.rpcservice.MachineManagerService;
import com.tbit.uqbike.service.rpcservice.MachineStatusService;
import com.tbit.uqbike.webmanager.business.vehicle_operation_report.enums.TimeDuration;
import com.tbit.uqbike.webmanager.util.StringUtil;
import com.tbit.uqbike.webmanager.util.csv.annotations.AsyncDownload;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.validation.Valid;
import javax.validation.constraints.NotNull;
import java.util.List;
import java.util.Map;
import java.util.Objects;

/**
 * @author MyWin E-mail:335918956@qq.com
 * @version 1.0
 * @createTime 2019-12-10 14:56
 */
@Slf4j
@Validated
@RestController
@RequestMapping(value = "/machineManager", produces = BaseController.MEDIA_JSON_UTF8)
public class MachineManagerController extends BaseController {
    @Autowired
    private MachineManagerService machineManagerService;
    @Autowired
    private MachineStatusService machineStatusService;

    /* 根据设备编号查询 */
    @RequestMapping("/getByKey")
    public JsonResult getByKey(@NotNull(message = "ver.key.notnull") String key, Integer mapType, Integer accountId, HttpServletRequest request) {
        LoginInfo info = getLogin(request);
        if (mapType == null) {
            mapType = SysConstant.GOOGLE;
        }

        MachineStatusFlag machineStatuse = machineManagerService.getByKey(info, accountId, key, mapType);

        return JsonResult.ok(machineStatuse);
    }

    /* 根据电量查询 */
    @RequestMapping("/getByPower")
    public JsonResult getByPower(Integer accountId, Integer soc, Integer mapType, Boolean sortByLast, Boolean sortByBatDt, Boolean sortByPosDt,
                                 Integer machineType, Integer rowCount, Integer pageNO, HttpServletRequest request, String regionIds) {
        LoginInfo info = getLogin(request);
        if (mapType == null) {
            mapType = SysConstant.GOOGLE;
        }
        if (sortByLast == null && sortByBatDt == null && sortByPosDt == null) {
            sortByBatDt = true;
        }
        if (soc == null) {
            soc = 30;
        }
        if (null == rowCount && null == pageNO) {
            // 全部获取
        } else {
            // 分页获取
            if (null == rowCount || rowCount <= 0 || rowCount > 1000) {
                rowCount = 20;
            }
            if (null == pageNO || pageNO < 1) {
                pageNO = 1;
            }
        }

        // 只有用户是代理商的时候允许为null
        if (null == accountId) {
            if (Objects.equals(info.type, UserConstant.USER_AGENT)) {
                accountId = info.id;
            } else {
                throw new BaseException(SystemCodeEnum.ACCOUNT_ID_NOT_VALID);
            }
        }

        List<Integer> regionList = StringUtil.getIntegerList(regionIds);
        PageData<List<MachineStatusFlag>> data = machineManagerService.getByPower(info, sortByLast, sortByBatDt, sortByPosDt, accountId, soc, mapType, rowCount, pageNO, machineType, regionList);
        return resultPageData(data, rowCount, pageNO);
    }

    @GetMapping("/exportByPower")
    public void exportByPower(Integer accountId, Boolean sortByLast, Boolean sortByBatDt, Boolean sortByPosDt, Integer soc, Integer mapType, Integer machineType, HttpServletRequest request, HttpServletResponse response) {
        LoginInfo info = getLogin(request);
        if (mapType == null) {
            mapType = SysConstant.GOOGLE;
        }
        if (sortByLast == null && sortByBatDt == null && sortByPosDt == null) {
            sortByBatDt = true;
        }
        if (soc == null) {
            soc = 30;
        }
        // 只有用户是代理商的时候允许为null
        if (null == accountId) {
            if (Objects.equals(info.type, UserConstant.USER_AGENT)) {
                accountId = info.id;
            } else {
                throw new BaseException(SystemCodeEnum.ACCOUNT_ID_NOT_VALID);
            }
        }
        export(machineManagerService.getByPower(info, sortByLast, sortByBatDt, sortByPosDt, accountId, soc, mapType, null, null, machineType, null), machineManagerService, response);
    }

    /* 查询所有设备 */
    @RequestMapping("/getAll")
    public JsonResult getAll(Integer accountId, Boolean sortByLast, Boolean sortByBatDt, Boolean sortByPosDt, Integer mapType, Integer machineType, Integer rowCount,
                             Integer pageNO, HttpServletRequest request, @RequestParam(required = false, value = "regionIds") String regionIds) {
        LoginInfo info = getLogin(request);
        if (mapType == null) {
            mapType = SysConstant.GOOGLE;
        }
        if (sortByLast == null && sortByBatDt == null && sortByPosDt == null) {
            sortByBatDt = true;
        }
        if (null == rowCount && null == pageNO) {
            // 全部获取
        } else {
            // 分页获取
            if (null == rowCount || rowCount <= 0 || rowCount > 1000) {
                rowCount = 20;
            }
            if (null == pageNO || pageNO < 1) {
                pageNO = 1;
            }
        }
        // 只有用户是代理商的时候允许为null
        if (null == accountId) {
            if (Objects.equals(info.type, UserConstant.USER_AGENT)) {
                accountId = info.id;
            } else {
                throw new BaseException(SystemCodeEnum.ACCOUNT_ID_NOT_VALID);
            }
        }
        List<Integer> regionList = StringUtil.getIntegerList(regionIds);
        PageData<List<MachineStatusFlag>> data = machineManagerService.getAll(info, sortByLast, sortByBatDt, sortByPosDt, accountId, mapType, rowCount, pageNO, machineType, regionList);

        return resultPageData(data, rowCount, pageNO);
    }


    @GetMapping("/exportByAll")
    public void exportByAll(Integer accountId, Boolean sortByLast, Boolean sortByBatDt, Boolean sortByPosDt, Integer mapType, Integer machineType, HttpServletRequest request, HttpServletResponse response, @RequestParam(value = "regionIds", required = false) String regionIds) {
        LoginInfo info = getLogin(request);
        if (mapType == null) {
            mapType = SysConstant.GOOGLE;
        }
        if (sortByLast == null && sortByBatDt == null && sortByPosDt == null) {
            sortByBatDt = true;
        }
        // 只有用户是代理商的时候允许为null
        if (null == accountId) {
            if (Objects.equals(info.type, UserConstant.USER_AGENT)) {
                accountId = info.id;
            } else {
                throw new BaseException(SystemCodeEnum.ACCOUNT_ID_NOT_VALID);
            }
        }
        List<Integer> regionList = StringUtil.getIntegerList(regionIds);
        export(machineManagerService.getAll(info, sortByLast, sortByBatDt, sortByPosDt, accountId, mapType, null, null, machineType, regionList), machineManagerService, response);
    }

    /* 闲置车辆查询 */
    @RequestMapping("/getByUnuse")
    public JsonResult getByUnuse(Integer accountId, Integer hours, Integer mapType, Boolean sortByLast, Boolean sortByBatDt, Boolean sortByPosDt,
                                 Integer machineType, Integer rowCount, Integer pageNO, HttpServletRequest request, String regionIds) {
        LoginInfo info = getLogin(request);
        if (mapType == null) {
            mapType = SysConstant.GOOGLE;
        }
        if (sortByLast == null && sortByBatDt == null && sortByPosDt == null) {
            sortByBatDt = true;
        }
        if (hours == null) {
            hours = 12;
        }
        if (null == rowCount && null == pageNO) {
            // 全部获取
        } else {
            // 分页获取
            if (null == rowCount || rowCount <= 0 || rowCount > 1000) {
                rowCount = 20;
            }
            if (null == pageNO || pageNO < 1) {
                pageNO = 1;
            }
        }
        if (null == accountId) {
            if (Objects.equals(info.type, UserConstant.USER_AGENT)) {
                accountId = info.id;
            } else {
                throw new BaseException(SystemCodeEnum.ACCOUNT_ID_NOT_VALID);
            }
        }
        List<Integer> regionIdList = StringUtil.getIntegerList(regionIds);
        PageData<List<MachineStatusFlag>> data = machineManagerService.getByUnuse(info, sortByLast, sortByBatDt, sortByPosDt, accountId, hours, mapType, rowCount, pageNO, machineType, regionIdList);

        return resultPageData(data, rowCount, pageNO);
    }

    @GetMapping("/exportByUnuse")
    public void exportByUnuse(Integer accountId, Boolean sortByLast, Boolean sortByBatDt, Boolean sortByPosDt, Integer hours, Integer mapType, Integer machineType, HttpServletRequest request, HttpServletResponse response, String regionIds) {
        LoginInfo info = getLogin(request);
        if (mapType == null) {
            mapType = SysConstant.GOOGLE;
        }
        if (sortByLast == null && sortByBatDt == null && sortByPosDt == null) {
            sortByBatDt = true;
        }
        // 只有用户是代理商的时候允许为null
        if (null == accountId) {
            if (Objects.equals(info.type, UserConstant.USER_AGENT)) {
                accountId = info.id;
            } else {
                throw new BaseException(SystemCodeEnum.ACCOUNT_ID_NOT_VALID);
            }
        }
        List<Integer> regionIdList = StringUtil.getIntegerList(regionIds);
        PageData<List<MachineStatusFlag>> getByUnuseExport = machineManagerService.getByUnuse(info, sortByLast, sortByBatDt, sortByPosDt, accountId, hours, mapType, null, null, machineType, regionIdList);

        export(getByUnuseExport, machineManagerService, response);
    }

    /* 故障车辆 */
    @RequestMapping("/getByFault")
    public JsonResult getByFault(Integer accountId, Integer mapType, Boolean sortByLast, Boolean sortByBatDt, Boolean sortByPosDt,
                                 Integer machineType, Integer rowCount, Integer pageNO, HttpServletRequest request, String regionIds) {
        LoginInfo info = getLogin(request);

        if (mapType == null) {
            mapType = SysConstant.GOOGLE;
        }
        if (sortByLast == null && sortByBatDt == null && sortByPosDt == null) {
            sortByBatDt = true;
        }
        if (null == rowCount && null == pageNO) {
            // 全部获取
        } else {
            // 分页获取
            if (null == rowCount || rowCount <= 0 || rowCount > 1000) {
                rowCount = 20;
            }
            if (null == pageNO || pageNO < 1) {
                pageNO = 1;
            }
        }
        if (null == accountId) {
            if (Objects.equals(info.type, UserConstant.USER_AGENT)) {
                accountId = info.id;
            } else {
                throw new BaseException(SystemCodeEnum.ACCOUNT_ID_NOT_VALID);
            }
        }
        List<Integer> regionList = StringUtil.getIntegerList(regionIds);

        PageData<List<MachineStatusFlag>> data = machineManagerService.getByFault(info, sortByLast, sortByBatDt, sortByPosDt, accountId, mapType, rowCount, pageNO, machineType, regionList);
        return resultPageData(data, rowCount, pageNO);
    }

    @GetMapping("/exportByFault")
    public void exportByFault(Integer accountId, Boolean sortByLast, Boolean sortByBatDt, Boolean sortByPosDt, Integer mapType, Integer machineType, HttpServletRequest request, HttpServletResponse response) {
        LoginInfo info = getLogin(request);
        if (mapType == null) {
            mapType = SysConstant.GOOGLE;
        }
        if (sortByLast == null && sortByBatDt == null && sortByPosDt == null) {
            sortByBatDt = true;
        }
        // 只有用户是代理商的时候允许为null
        if (null == accountId) {
            if (Objects.equals(info.type, UserConstant.USER_AGENT)) {
                accountId = info.id;
            } else {
                throw new BaseException(SystemCodeEnum.ACCOUNT_ID_NOT_VALID);
            }
        }
        export(machineManagerService.getByFault(info, sortByLast, sortByBatDt, sortByPosDt, accountId, mapType, null, null, machineType, null), machineManagerService, response);
    }

    /* 异常车辆 */
    @RequestMapping("/getByAbnormal")
    public JsonResult getByAbnormal(Integer accountId, Integer abnormalType, Integer mapType, Boolean sortByLast, Boolean sortByBatDt, Boolean sortByPosDt,
                                    Integer machineType, Integer rowCount, Integer pageNO, HttpServletRequest request, String regionIds) {
        LoginInfo info = getLogin(request);
        if (sortByLast == null && sortByBatDt == null && sortByPosDt == null) {
            sortByBatDt = true;
        }
        if (mapType == null) {
            mapType = SysConstant.GOOGLE;
        }
        if (null == rowCount && null == pageNO) {
            // 全部获取
        } else {
            // 分页获取
            if (null == rowCount || rowCount <= 0 || rowCount > 1000) {
                rowCount = 20;
            }
            if (null == pageNO || pageNO < 1) {
                pageNO = 1;
            }
        }
        if (null == accountId) {
            if (Objects.equals(info.type, UserConstant.USER_AGENT)) {
                accountId = info.id;
            } else {
                throw new BaseException(SystemCodeEnum.ACCOUNT_ID_NOT_VALID);
            }
        }
        List<Integer> regionList = StringUtil.getIntegerList(regionIds);
        PageData<List<MachineStatusFlag>> data = machineManagerService.getByAbnormal(info, sortByLast, sortByBatDt, sortByPosDt, accountId, abnormalType, mapType, rowCount, pageNO, machineType, regionList);

        return resultPageData(data, rowCount, pageNO);
    }

    @GetMapping("/exportByAbnormal")
    public void exportByAbnormal(Integer accountId, Boolean sortByLast, Boolean sortByBatDt, Boolean sortByPosDt, Integer abnormalType, Integer mapType, Integer machineType, String regionIds, HttpServletRequest request, HttpServletResponse response) {
        LoginInfo info = getLogin(request);
        if (mapType == null) {
            mapType = SysConstant.GOOGLE;
        }
        if (sortByLast == null && sortByBatDt == null && sortByPosDt == null) {
            sortByBatDt = true;
        }
        // 只有用户是代理商的时候允许为null
        if (null == accountId) {
            if (Objects.equals(info.type, UserConstant.USER_AGENT)) {
                accountId = info.id;
            } else {
                throw new BaseException(SystemCodeEnum.ACCOUNT_ID_NOT_VALID);
            }
        }
        List<Integer> regionList = StringUtil.getIntegerList(regionIds);
        export(machineManagerService.getByAbnormal(info, sortByLast, sortByBatDt, sortByPosDt, accountId, abnormalType, mapType, null, null, machineType, regionList), machineManagerService, response);
    }


    /**
     * 车辆状态统计列表
     *
     * @param accountIds 区域ids 多个区域用,拼接 示例1,2,3,4
     * @param startTime  开始时间 示例: 2023-01-01 11
     * @param endTime    结束时间 示例: 2023-01-01 11
     * @param rowCount   每页条数 默认10
     * @param pageNO     页码 默认1
     * @param duration   时间维度 HOUR-小时 DAY-天
     * @return result
     */
    @GetMapping("/operations/stat")
    public Result<PageResult<MachineOperationsStat>> selectMachineOperationsStatPage(@NotNull(message = "请选择运营区域") String accountIds,
                                                                                     String startTime, String endTime,String orderBy,
                                                                                     @RequestParam(defaultValue = "10") Integer rowCount,
                                                                                     @RequestParam(defaultValue = "1") Integer pageNO,
                                                                                     @RequestParam(defaultValue = "HOUR") TimeDuration duration
    ) {
        Page<MachineOperationsStat> pageResult = machineManagerService.selectMachineOperationsStatPage(accountIds, startTime, endTime, orderBy, rowCount, pageNO, duration);
        return Result.successPage(pageNO, rowCount, (int) pageResult.getTotal(), pageResult.getRecords());
    }

    /**
     * 车辆状态统计列表导出csv
     * @param machineOperationsStatDownloadDTO 下载对象
     * @return result
     */
    @GetMapping("/operations/stat/export")
    @AsyncDownload(defaultFileName = "车辆状态数据统计")
    public Result<String> machineOperationsStatExportCsv(
            @Valid MachineOperationsStatDownloadDTO machineOperationsStatDownloadDTO) {
        String url = machineManagerService.machineOperationsStatExportCsv(machineOperationsStatDownloadDTO);
        return Result.success(url);
    }

    /**
     * 车辆状态统计列表导出
     * @param machineOperationsStatDownloadDTO 入参
     * @return result
     */
    @GetMapping("/operations/stat/exportExcel")
    public Result<Object> machineOperationsStatExport(@Valid MachineOperationsStatDownloadDTO machineOperationsStatDownloadDTO) {
        return machineManagerService.machineOperationsStatExport(machineOperationsStatDownloadDTO);
    }

    /**
     * 车辆状态统计-收入和骑行
     *
     * @param startTime  开始时间(小时、天、月 都需要拼接小时) 示例: 2023-01-01 11
     * @param endTime    结束时间(同上) 示例: 2023-01-01 11
     * @param accountIds 分区id 多个分区用,拼接 示例1,2,3,4
     * @param dateType   1-小时  2-天  3-按月
     * @return result
     */
    @GetMapping("/operations/stat/chart")
    public Result<List<MachineOperationsStatChartVO>> selectMachineOperationsStatChart(
            @NotNull(message = "请选择运营区域") String accountIds,
            String startTime, String endTime,
            @RequestParam(defaultValue = "1") Integer dateType
    ) {
        List<MachineOperationsStatChartVO> resultList = machineManagerService.selectMachineOperationsStatChart(accountIds, startTime, endTime, dateType);
        return Result.success(resultList);
    }


    /* 统计异常车辆 */
    @RequestMapping("/getByUse")
    public JsonResult getByUse(Integer accountId, Integer mapType, Boolean sortByLast, Boolean sortByBatDt, Boolean sortByPosDt,
                               Integer machineType, Integer rowCount, Integer pageNO, HttpServletRequest request, String regionIds) {
        LoginInfo info = getLogin(request);
        if (sortByLast == null && sortByBatDt == null && sortByPosDt == null) {
            sortByBatDt = true;
        }
        if (mapType == null) {
            mapType = SysConstant.GOOGLE;
        }
        if (null == rowCount && null == pageNO) {
            // 全部获取
        } else {
            // 分页获取
            if (null == rowCount || rowCount <= 0 || rowCount > 1000) {
                rowCount = 20;
            }
            if (null == pageNO || pageNO < 1) {
                pageNO = 1;
            }
        }
        if (null == accountId) {
            if (Objects.equals(info.type, UserConstant.USER_AGENT)) {
                accountId = info.id;
            } else {
                throw new BaseException(SystemCodeEnum.ACCOUNT_ID_NOT_VALID);
            }
        }
        List<Integer> regionIdList = StringUtil.getIntegerList(regionIds);
        PageData<List<MachineStatusFlag>> data = machineManagerService.getByUse(info, sortByLast, sortByBatDt, sortByPosDt, accountId, mapType, rowCount, pageNO, machineType, regionIdList);

        return resultPageData(data, rowCount, pageNO);
    }

    @GetMapping("/exportByUse")
    public void exportByUse(Integer accountId, Boolean sortByLast, Boolean sortByBatDt, Boolean sortByPosDt, Integer mapType, Integer machineType, HttpServletRequest request, HttpServletResponse response) {
        LoginInfo info = getLogin(request);
        if (mapType == null) {
            mapType = SysConstant.GOOGLE;
        }
        if (sortByLast == null && sortByBatDt == null && sortByPosDt == null) {
            sortByBatDt = true;
        }
        // 只有用户是代理商的时候允许为null
        if (null == accountId) {
            if (Objects.equals(info.type, UserConstant.USER_AGENT)) {
                accountId = info.id;
            } else {
                throw new BaseException(SystemCodeEnum.ACCOUNT_ID_NOT_VALID);
            }
        }
        export(machineManagerService.getByUse(info, sortByLast, sortByBatDt, sortByPosDt, accountId, mapType, null, null, machineType, null), machineManagerService, response);
    }

    /* 获取车辆信息 */
    @RequestMapping("/getMachineInfo")
    public JsonResult getMachineInfo(Integer mapType, @NotNull(message = "ver.machineId.notnull") Integer machineId, HttpServletRequest request) {
        LoginInfo info = getLogin(request);
        if (mapType == null) {
            mapType = SysConstant.GOOGLE;
        }

        MachineInfo machineInfo = machineStatusService.getMachineInfo(info, machineId, mapType);

        return JsonResult.ok(machineInfo);
    }

    /* 统计异常车辆 */
    @RequestMapping("/statAbnormal")
    public JsonResult statAbnormal(Integer accountId, HttpServletRequest request, String regionIds) {
        LoginInfo info = getLogin(request);
        if (null == accountId) {
            if (Objects.equals(info.type, UserConstant.USER_AGENT)) {
                accountId = info.id;
            } else {
                throw new BaseException(SystemCodeEnum.ACCOUNT_ID_NOT_VALID);
            }
        }
        List<Integer> regionList = StringUtil.getIntegerList(regionIds);

        Map<String, Integer> map = machineManagerService.statAbnormal(info, accountId, regionList);
        return JsonResult.ok(map);
    }

    private JsonResult resultPageData(PageData<List<MachineStatusFlag>> data, Integer rowCount, Integer pageNO) {
        if (null == rowCount && null == pageNO) {
            return JsonResult.ok(data.getData());
        } else {
            return JsonResult.ok(data.getData(), data.getTotal());
        }
    }

}
